home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP12.ZIP / PATRON / TENANT.CPP < prev    next >
C/C++ Source or Header  |  1993-07-19  |  41KB  |  1,665 lines

  1. /*
  2.  * TENANT.CPP
  3.  * Modifications for Chapter 12
  4.  *
  5.  * Implementation of the CTentant class which holds information
  6.  * for a single object on a page.  It maintains position, references
  7.  * to data, and a storage.
  8.  *
  9.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  10.  *
  11.  * Kraig Brockschmidt, Software Design Engineer
  12.  * Microsoft Systems Developer Relations
  13.  *
  14.  * Internet  :  kraigb@microsoft.com
  15.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  16.  */
  17.  
  18.  
  19. #include "patron.h"
  20.  
  21.  
  22. /*
  23.  * CTenant::CTenant
  24.  * CTenant::~CTenant
  25.  *
  26.  * Constructor Parameters:
  27.  *  dwID            DWORD identifier for this page.
  28.  *  hWnd            HWND of the pages window.
  29.  *  pPG             LPCPages to the parent structure.
  30.  */
  31.  
  32. CTenant::CTenant(DWORD dwID, HWND hWnd, LPCPages pPG)
  33.     {
  34.     m_hWnd=hWnd;
  35.     m_dwID=dwID;
  36.  
  37.     m_fInitialized=0;
  38.     m_pIStorage=NULL;
  39.     m_cOpens=0;
  40.  
  41.     m_pObj=NULL;
  42.     m_pPG =pPG;
  43.  
  44.     m_cRef=0;
  45.     m_pIOleObject=NULL;
  46.     m_pIViewObject=NULL;
  47.  
  48.     m_pIOleClientSite=NULL;
  49.     m_pIAdviseSink=NULL;
  50.  
  51.     //CHAPTER12MOD
  52.     m_pmkFile=NULL;
  53.     m_fLinkAvail=TRUE;          //Checked on FLoad.
  54.     //End CHAPTER12MOD
  55.     return;
  56.     }
  57.  
  58.  
  59. CTenant::~CTenant(void)
  60.     {
  61.     //CHAPTER12MOD
  62.     if (NULL!=m_pmkFile)
  63.         m_pmkFile->Release();
  64.     //End CHAPTER12MOD
  65.  
  66.     if (NULL!=m_pIViewObject)
  67.         {
  68.         m_pIViewObject->SetAdvise(m_fe.dwAspect, 0, NULL);
  69.         m_pIViewObject->Release();
  70.         }
  71.  
  72.     if (NULL!=m_pIOleObject)
  73.         m_pIOleObject->Release();
  74.  
  75.     //We delete our own interfaces since we control them
  76.     if (NULL!=m_pIAdviseSink)
  77.         delete m_pIAdviseSink;
  78.  
  79.     if (NULL!=m_pIOleClientSite)
  80.         delete m_pIOleClientSite;
  81.  
  82.     if (NULL!=m_pObj)
  83.         {
  84.         //We know we only hold one reference from UCreate or FLoad
  85.         m_pObj->Release();
  86.         m_pObj=NULL;
  87.         }
  88.  
  89.     return;
  90.     }
  91.  
  92.  
  93.  
  94.  
  95. /*
  96.  * CTenant::QueryInterface
  97.  * CTenant::AddRef
  98.  * CTenant::Release
  99.  *
  100.  * Purpose:
  101.  *  IUnknown members for CTenant object.
  102.  */
  103.  
  104. STDMETHODIMP CTenant::QueryInterface(REFIID riid, LPLPVOID ppv)
  105.     {
  106.     *ppv=NULL;
  107.  
  108.     if (IsEqualIID(riid, IID_IUnknown))
  109.         *ppv=(LPVOID)this;
  110.  
  111.     if (IsEqualIID(riid, IID_IOleClientSite))
  112.         *ppv=(LPVOID)m_pIOleClientSite;
  113.  
  114.     if (IsEqualIID(riid, IID_IAdviseSink))
  115.         *ppv=(LPVOID)m_pIAdviseSink;
  116.  
  117.     if (NULL!=*ppv)
  118.         {
  119.         ((LPUNKNOWN)*ppv)->AddRef();
  120.         return NOERROR;
  121.         }
  122.  
  123.     return ResultFromScode(E_NOINTERFACE);
  124.     }
  125.  
  126.  
  127. STDMETHODIMP_(ULONG) CTenant::AddRef(void)
  128.     {
  129.     return ++m_cRef;
  130.     }
  131.  
  132. STDMETHODIMP_(ULONG) CTenant::Release(void)
  133.     {
  134.     ULONG           cRefT;
  135.  
  136.     cRefT=--m_cRef;
  137.  
  138.     if (0L==m_cRef)
  139.         delete this;
  140.  
  141.     return cRefT;
  142.     }
  143.  
  144.  
  145.  
  146.  
  147.  
  148.  
  149. /*
  150.  * CTenant::GetID
  151.  *
  152.  * Return Value:
  153.  *  DWORD           dwID field in this tenant.  This function is only here
  154.  *                  to avoid hiding inline implementations in pages.h
  155.  */
  156.  
  157. DWORD CTenant::GetID(void)
  158.     {
  159.     return m_dwID;
  160.     }
  161.  
  162.  
  163.  
  164.  
  165.  
  166. /*
  167.  * CTenant::GetStorageName
  168.  *
  169.  * Parameters:
  170.  *  pszName         LPSTR to a buffer in which to store the storage name
  171.  *                  for this tenant.
  172.  *
  173.  * Return Value:
  174.  *  UINT            Number of characters stored.
  175.  */
  176.  
  177. UINT CTenant::GetStorageName(LPSTR pszName)
  178.     {
  179.     return wsprintf(pszName, "Tenant %lu", m_dwID);
  180.     }
  181.  
  182.  
  183.  
  184.  
  185.  
  186. /*
  187.  * CTenant::UCreate
  188.  *
  189.  * Purpose:
  190.  *  Creates a new tenant of the given CLSID, which can be either a
  191.  *  static bitmap or metafile now (Chapter 7) and which may eventually
  192.  *  be any OLE object.
  193.  *
  194.  * Parameters:
  195.  *  tType           TENANTTYPE to create, either a static metafile, bitmap,
  196.  *                  or some kind of OLE object (later chapters)
  197.  *                  This determined which OleCreate* call we use.
  198.  *  pvType          LPVOID providing the relevant pointer from which
  199.  *                  to create the tenant, depending on iType.
  200.  *  pFE             LPFORMATETC specifying the type of renderings to use.
  201.  *  pptl            LPPOINTL in which we can store offset coordinates.
  202.  *  pszl            LPSIZEL where this object should store its lometric extents.
  203.  *  pIStorage       LPSTORAGE of the page we live in.  We have to
  204.  *                  create another storage under this for the tenant.
  205.  *  ppo             LPPATRONOBJECT containing placement data.
  206.  *  dwData          DWORD containing extra data, sensitive to iType.
  207.  *
  208.  * Return Value:
  209.  *  UINT            A UCREATE_* value depending on what we actually do.
  210.  */
  211.  
  212. UINT CTenant::UCreate(TENANTTYPE tType, LPVOID pvType, LPFORMATETC pFE
  213.     , LPPOINTL pptl, LPSIZEL pszl, LPSTORAGE pIStorage
  214.     , LPPATRONOBJECT ppo, DWORD dwData)
  215.     {
  216.     HRESULT             hr;
  217.     LPUNKNOWN           pObj;
  218.     UINT                uRet=UCREATE_GRAPHICONLY;
  219.  
  220.     if (NULL==pvType || NULL==pIStorage)
  221.         return UCREATE_FAILED;
  222.  
  223.     //Fail if this is called for an already living tenant.
  224.     if (m_fInitialized)
  225.         return UCREATE_FAILED;
  226.  
  227.     m_fInitialized=TRUE;
  228.  
  229.     //Create a new storage for this tenant.
  230.     if (!FOpen(pIStorage))
  231.         return UCREATE_FAILED;
  232.  
  233.     /*
  234.      * Get the placement info if it's here.  We either have a non-NULL
  235.      * LPPATRONOBJECT in ppo or we have to use default placement and
  236.      * retrieve the size from the object itself.
  237.      */
  238.     pszl->cx=0;
  239.     pszl->cy=0;
  240.  
  241.     if (NULL!=ppo)
  242.         {
  243.         *pFE=ppo->fe;
  244.         *pptl=ppo->ptl;
  245.         *pszl=ppo->szl;     //Could be 0,0 in which case we ask object
  246.  
  247.         uRet=UCREATE_PLACEDOBJECT;
  248.         }
  249.  
  250.     hr=ResultFromScode(E_FAIL);
  251.  
  252.     //Now create an object based specifically for the type.
  253.     switch (tType)
  254.         {
  255.         case TENANTTYPE_NULL:
  256.             break;
  257.  
  258.         case TENANTTYPE_STATIC:
  259.             /*
  260.              * We could use OleCreateStaticFromData here which does
  261.              * pretty much what we're doing below.  However, it does
  262.              * not allow us to control whether we paste a bitmap or
  263.              * a metafile--it uses metafile first, bitmap second.  For
  264.              * this reason we'll use code developed in Chapter 6's
  265.              * FreeLoader to affect the paste.
  266.              */
  267.             hr=CreateStatic((LPDATAOBJECT)pvType, pFE, &pObj);
  268.             break;
  269.  
  270.         case TENANTTYPE_EMBEDDEDOBJECT:
  271.             hr=OleCreate(*((LPCLSID)pvType), IID_IUnknown, OLERENDER_DRAW
  272.                 , NULL, NULL, m_pIStorage, (LPLPVOID)&pObj);
  273.             break;
  274.  
  275.         case TENANTTYPE_EMBEDDEDFILE:
  276.             hr=OleCreateFromFile(CLSID_NULL, (LPSTR)pvType, IID_IUnknown
  277.                 , OLERENDER_DRAW, NULL, NULL, m_pIStorage, (LPLPVOID)&pObj);
  278.             break;
  279.  
  280.         case TENANTTYPE_EMBEDDEDOBJECTFROMDATA:
  281.             hr=OleCreateFromData((LPDATAOBJECT)pvType, IID_IUnknown
  282.                 , OLERENDER_DRAW, NULL, NULL, m_pIStorage, (LPLPVOID)&pObj);
  283.             break;
  284.  
  285.         //CHAPTER12MOD
  286.         case TENANTTYPE_LINKEDFILE:
  287.             hr=OleCreateLinkToFile((LPSTR)pvType, IID_IUnknown
  288.                 , OLERENDER_DRAW, NULL, NULL, m_pIStorage, (LPLPVOID)&pObj);
  289.             break;
  290.  
  291.         case TENANTTYPE_LINKEDOBJECTFROMDATA:
  292.             hr=OleCreateLinkFromData((LPDATAOBJECT)pvType, IID_IUnknown
  293.                 , OLERENDER_DRAW, NULL, NULL, m_pIStorage, (LPLPVOID)&pObj);
  294.             break;
  295.         //End CHAPTER12MOD
  296.  
  297.         default:
  298.             break;
  299.         }
  300.  
  301.     //If creation didn't work, get rid for the element FOpen created.
  302.     if (FAILED(hr))
  303.         {
  304.         Destroy(pIStorage);
  305.         return UCREATE_FAILED;
  306.         }
  307.  
  308.     //We don't get the size if PatronObject data was seen already.
  309.     FObjectInitialize(pObj, pFE, dwData);
  310.  
  311.     //We depend here on m_pIOleObject having been initialized.
  312.     if ((0==pszl->cx && 0==pszl->cy))
  313.         {
  314.         SIZEL   szl;
  315.  
  316.         //Try to get the real size of the object, default to 2"*2"
  317.         SETSIZEL((*pszl), 2*LOMETRIC_PER_INCH, 2*LOMETRIC_PER_INCH);
  318.  
  319.